package com.example.mq.filter;

import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 邹宇杰
 * @email 2901570623@qq.com
 * @date 2022/3/18 9:30
 */
@Slf4j
public class LoginUsernamePasswordTokenFilter extends UsernamePasswordAuthenticationFilter {

    private UserDetailsService userDetailsService;

    private AuthenticationManager authenticationManager;

    public LoginUsernamePasswordTokenFilter(AuthenticationManager authenticationManager, UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
        this.authenticationManager = authenticationManager;
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        String token = Jwts.builder()
                .setSubject(authResult.getName())
                .setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 24 * 1000))
                .signWith(SignatureAlgorithm.HS512, "demo1")
                .compact();
        Map<String, String> map = new HashMap<>();
        map.put("code", "200");
        map.put("message", "登录成功");
        map.put("token", token);
        response.getOutputStream().write(JSONObject.toJSONString(map.toString()).getBytes(StandardCharsets.UTF_8));
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html");
        log.error(failed.getMessage());
        response.getOutputStream().write("账号密码错误".getBytes(StandardCharsets.UTF_8));
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        log.info(JSONObject.toJSONString(userDetails));
        return this.authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities()));
    }
}
